import { defineStore } from 'pinia';
import {
  getFileList,
  deleteFile,
  deleteFolder,
  searchFile,
  getShareList,
  addShare,
  deleteShare,
  delFileList,
  downloadPoints,
  deleteFileLog,
  deleteFolderLog,
  recoverFolder,
  recoverFile
} from '@/apis/file';
import { FlipDrag } from '@/utils/filpDrag';
import http from '@/utils/http';
import { set } from 'vue-demi';

export const SORT_TYPE = {
  DATE: 'create_time',
  FILE_NAME: 'name'
};
export const SORT_ORDER = {
  ASC: 'asc',
  DESC: 'desc'
};
let curControlledContainer = null;
let curContainer = null;

const createShareLink = (shareId, userId) => {
  const id = btoa(`${shareId}`);
  return `${location.origin}/share/${id}`;
};

export const useFileStore = defineStore('file', {
  state: () => {
    return {
      curFolderId: 0,
      curFolderInfo: {},
      curFileInfo: {},
      prevFolders: [],
      curFileList: [],
      curFolderList: [],
      curSortFunc: () => 1,
      curSortType: SORT_TYPE.DATE,
      curSortOrder: SORT_ORDER.ASC,
      curUploadTasks: new Set(),
      isGridironPlan: true,
      curSearchedFileList: [],
      curSearchKeyword: '',
      curShareList: [],
      type: '',
      schedule: '',
      // 大小文件 1大文件 2小文件
      Type: 1,
      visible: false,
      delFilesList: []
    };
  },

  actions: {
    optimizeFunctions: async function (option) {
      try {
        const promiseArr = this.delFilesList
          .map((item) => {
            if (option === 'del') {
              return item.type === 'folder'
                ? deleteFolder({ folder_id: item.folder_id })
                : deleteFile({ file_id: item.file_id });
            } else if (option === 'Cancel') {
              return item.type === 'folder'
                ? deleteFolderLog({ folder_id: item.folder_id })
                : deleteFileLog({ file_id: item.file_id });
            } else if (option === 'recover') {
              return item.type === 'folder'
                ? recoverFolder({ folder_id: item.folder_id })
                : recoverFile({ file_id: item.file_id });
            }
            return null; // Handle unsupported option gracefully
          })
          .filter((promise) => promise !== null);
        await Promise.all(promiseArr);
        this.visible = false;
      } catch (error) {
        console.error('Error optimizing functions:', error);
      }
    },

    setdelFileList(list) {
      this.delFilesList = list;
    },

    setVisible(vis) {
      if (vis === 1) {
        this.visible = false;
        return;
      }
      this.visible = !this.visible;
    },

    setType(type) {
      this.Type = type;
    },

    setSchedule(schedule) {
      this.schedule = schedule;
    },

    clearSchedule() {
      this.schedule = 0;
    },

    updateFileList: async function (folderId) {
      const { data } = await getFileList({
        page: 1,
        limit: 9999999,
        folder_id: folderId,
        type: this.Type
      });
      const { data: shareData } = await getShareList({
        page: 1,
        limit: 9999999
      });
      this.curShareList = shareData
        .filter((s) => s.file !== null && s.file.is_del === 0)
        .map((s) => {
          // 生成分享链接
          const shareLink = createShareLink(s.share_id, s.user_id);
          s.file.share_link = shareLink;
          s.file.share = true;
          s.file.share_id = s.share_id;
          s.file.expire_time = s.expire_time;
          s.file.code = s.code;
          // 为当前选中文件添加分享信息
          if (s.file_id === this.curFileInfo.file_id) {
            this.setCurFileInfo({
              ...this.curFileInfo,
              share: true,
              share_link: shareLink,
              share_id: s.share_id,
              expire_time: s.expire_time,
              code: s.code,
              Type: this.curFileInfo.type
            });
          }

          return s;
        });

      this.curFolderId = folderId;
      this.curFileList = data.file.map((f) => {
        const index = this.curShareList.findIndex(
          (s) => s.file_id === f.file_id
        );
        f.share = index === -1 ? false : true;
        f.share_link =
          index === -1 ? '' : this.curShareList[index].file.share_link;
        f.share_id = index === -1 ? '' : this.curShareList[index].share_id;
        f.expire_time =
          index === -1 ? '' : this.curShareList[index].expire_time;
        f.code = index === -1 ? '' : this.curShareList[index].code;
        f.Type = f.type;
        return f;
      });
      this.curFolderList = data.folder;
      this.switchSortFunc(this.curSortType, this.curSortOrder);

      return true;
    },
    shareFile: async function (data) {
      await addShare({
        file_id: data.file_id,
        expire_time: data.expire_time,
        code: data.code
      });
      await this.updateFileList(this.curFolderId);
      return true;
    },
    deleteShareFile: async function (shareId) {
      await deleteShare({ share_id: shareId });
      await this.updateFileList(this.curFolderId);
      this.setCurFileInfo({
        ...this.curFileInfo,
        share: false,
        share_link: '',
        share_id: '',
        expire_time: '',
        code: ''
      });
      return true;
    },
    updateShareFile: async function (data) {
      await deleteShare({ share_id: data.share_id });
      await addShare({
        file_id: data.file_id,
        expire_time: data.expire_time,
        code: data.code
      });
      await this.updateFileList(this.curFolderId);
      return true;
    },
    updateCurSearchedFileList: async function (keyword) {
      const { data } = await searchFile({
        search: keyword,
        page: 1,
        limit: 9999999
      });
      this.curSearchedFileList = data || [];
      return true;
    },
    setSearchedKeyword: async function (keyword) {
      this.curSearchKeyword = keyword;
      await this.updateCurSearchedFileList(keyword);
      return true;
    },
    deleteFile: async function (file, mode) {
      if (mode === 1) {
        if (file.file_id) {
          await deleteFile({ file_id: file.file_id });
        } else if (file.folder_id) {
          await deleteFolder({ folder_id: file.folder_id });
        }
        this.setCurFileInfo({});
        this.updateFileList(this.curFolderId);
      }
      if (mode === 2) {
        if (file.file_id) {
          await deleteFileLog({ file_id: file.file_id });
        } else if (file.folder_id) {
          await deleteFolderLog({ folder_id: file.folder_id });
        }
        this.getdelFileList(0, 'trash');
      }
    },

    entryFolder: async function (folderId, type = '') {
      this.curFolderId = folderId;
      this.type = type;
      this.setCurFileInfo({});
      if (folderId !== 0) {
        this.prevFolders.push(this.curFolderInfo);
        const folderInfo = this.curFolderList.find(
          (f) => f.folder_id === folderId
        );
        this.setCurFolderInfo(folderInfo);
      }
      await this.updateFileList(folderId);
    },
    // 返回上一页
    backToParentFolder: async function () {
      if (this.prevFolders.length === 0) return;
      const prevFolder = this.prevFolders.pop();
      this.setCurFolderInfo(prevFolder);
      this.curFolderId = prevFolder.folder_id;
      this.setCurFileInfo({});
      await this.updateFileList(prevFolder.folder_id);
    },
    setCurFileInfo: function (fileInfo) {
      this.curFileInfo = fileInfo;
    },
    setCurFolderInfo: function (folderInfo) {
      this.curFolderInfo = folderInfo;
    },
    setContainer(container) {
      curControlledContainer = new FlipDrag(container);
      curContainer = container;
      this.switchSortFunc(this.curSortType, this.curSortOrder);
    },
    sort(fn) {
      this.curFileList.sort(fn);
      this.curFolderList.sort(fn);
    },
    switchSortFunc(type, order) {
      // 根据 type 和 order 生成排序函数
      this.curSortType = type;
      this.curSortOrder = order;

      const sortFunc = this.createSortFunc(type, order);
      this.sort(sortFunc);
    },
    createSortFunc(type, order) {
      let sortFunc;
      switch (type) {
        case SORT_TYPE.DATE:
          sortFunc = (a, b) => {
            const timeStampA = new Date(a[SORT_TYPE.DATE]).valueOf();
            const timeStampB = new Date(b[SORT_TYPE.DATE]).valueOf();
            if (order === SORT_ORDER.ASC) {
              return timeStampA - timeStampB;
            } else if (order === SORT_ORDER.DESC) {
              return timeStampB - timeStampA;
            }
            return 1;
          };
          break;
        case SORT_TYPE.FILE_NAME:
          sortFunc = (a, b) => {
            if (order === SORT_ORDER.ASC) {
              return a[SORT_TYPE.FILE_NAME].localeCompare(
                b[SORT_TYPE.FILE_NAME]
              );
            } else if (order === SORT_ORDER.DESC) {
              return b[SORT_TYPE.FILE_NAME].localeCompare(
                a[SORT_TYPE.FILE_NAME]
              );
            } else {
              return 1;
            }
          };
          break;
      }
      this.curSortFunc = sortFunc;
      return sortFunc;
    },
    toggleGridironPlan(value) {
      this.isGridironPlan = value;
      this.switchSortFunc(this.curSortType, this.curSortOrder);
    },
    addUploadTask(uploadTask) {
      this.curUploadTasks.add(uploadTask);
      uploadTask
        .then((res) => {
          this.curUploadTasks.delete(uploadTask);
        })
        .catch((res) => {
          this.curUploadTasks.delete(uploadTask);
        });
    },
    flip() {
      if (curControlledContainer) {
        return curControlledContainer.flip();
      }
      return () => {};
    },
    checkIsFolder(fileInfo) {
      return !!(
        (fileInfo.folder_id || fileInfo.folder_id === 0) &&
        !fileInfo.file_id &&
        fileInfo.file_id !== 0 &&
        (fileInfo.user_id || fileInfo.user_id === 0)
      );
    },
    checkIsFile(fileInfo) {
      return fileInfo.file_id || fileInfo.file_id === 0;
    },
    checkShareExpired(expireTime) {
      return Date.now() / 1000 >= +expireTime;
    },

    down: async function (fileInfo) {
      const blob = await http(fileInfo.url, { responseType: 'blob' });
      const a = document.createElement('a');
      const url = URL.createObjectURL(blob);
      a.href = url;
      a.download = fileInfo.name;
      a.click();
      URL.revokeObjectURL(url);
    },

    downloadFile: async function (fileInfo) {
      if (!fileInfo.url) return false;
      if (fileInfo.Type === 2) {
        this.down(fileInfo);
        return true;
      } else {
        const res = await downloadPoints({ file_id: fileInfo.file_id });
        if (res.status === 0) {
          this.down(fileInfo);
          return true;
        } else {
          return false;
        }
      }
    },
    getdelFileList: async function (folderId, type = '') {
      this.curFolderId = folderId;
      this.type = type;
      this.setCurFileInfo({});
      const { data } = await delFileList({
        page: 1,
        limit: 9999999,
        folder_id: folderId
      });
      this.curFileList = data.file.map((f) => {
        const index = this.curShareList.findIndex(
          (s) => s.file_id === f.file_id
        );
        f.share = index === -1 ? false : true;
        f.share_link =
          index === -1 ? '' : this.curShareList[index].file.share_link;
        f.share_id = index === -1 ? '' : this.curShareList[index].share_id;
        f.expire_time =
          index === -1 ? '' : this.curShareList[index].expire_time;
        f.code = index === -1 ? '' : this.curShareList[index].code;
        return f;
      });
      this.curFolderList = data.folder;
      this.switchSortFunc(this.curSortType, this.curSortOrder);

      return true;
    },
    getdownloadPoints: async function ({ file_id, Type }) {
      if (!file_id) return false;
      if (Type === 2) return true;
      const res = await downloadPoints({ file_id });
      if (res.status === 0) {
        return true;
      } else {
        return false;
      }
    }
  }
});
